home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 12 / Amiga Format AFCD12 (Apr 1997, Issue 96).iso / -in_the_mag- / emulation / fs1541 / main.c < prev    next >
C/C++ Source or Header  |  1997-02-09  |  5KB  |  220 lines

  1. /*
  2.     FS1541
  3.  
  4.     main.c
  5.  
  6.     The handler entry point.
  7.  
  8. */
  9.  
  10. #include <string.h>
  11.  
  12. #include <exec/types.h>
  13. #include <exec/execbase.h>
  14. #include <dos/dosextens.h>
  15. #include <dos/dostags.h>
  16. #include <dos/filehandler.h>
  17. #include <utility/utility.h>
  18. #include <devices/timer.h>
  19.  
  20. #include <proto/exec.h>
  21. #include <proto/dos.h>
  22.  
  23. #include "main.h"
  24. #include "packet.h"
  25. #include "disk.h"
  26. #include "volume.h"
  27. #include "support.h"
  28.  
  29. char verstring[] = "$VER: 1541-handler 1.0 (20.1.97)";
  30.  
  31. struct ExecBase *SysBase;
  32. struct DosLibrary *DOSBase;
  33. struct UtilityBase *UtilityBase, *__UtilityBase;
  34.  
  35. struct Task *ourtask;
  36. struct MsgPort *ourport;
  37.  
  38. struct FileSysStartupMsg *fssm;
  39.  
  40. static BOOL MakeFSSM(BSTR);
  41.  
  42. /*-------------------------------------------------------------------------*/
  43.  
  44. void entry(void)
  45. {
  46.     struct DosPacket *startuppacket;
  47.     struct DosList *devnode;
  48.     LONG error = ERROR_NO_FREE_STORE;
  49.  
  50.     SysBase = *(volatile APTR*)4;
  51.  
  52.     ourtask = FindTask(NULL);
  53.  
  54.     ourport = &((struct Process *)ourtask)->pr_MsgPort;
  55.     WaitPort(ourport);
  56.     startuppacket = GetPacket(ourport);
  57.  
  58.     devnode = (struct DosList*)BADDR(startuppacket->dp_Arg3);
  59.  
  60.     if((DOSBase = (struct DosLibrary*)OpenLibrary(DOSNAME, 37)))
  61.     {
  62.         if((UtilityBase = (struct UtilityBase*)OpenLibrary("utility.library",37)))
  63.         {
  64.             __UtilityBase = UtilityBase;
  65.  
  66.             /* I'm almost sure that using the MountList `Control' field
  67.                instead of `Startup' is better; well... next time ;-) */
  68.             if(MakeFSSM(startuppacket->dp_Arg2))
  69.             {
  70.                 devnode->dol_misc.dol_handler.dol_Startup = (BPTR)MKBADDR(fssm);
  71.  
  72.                 if(!(error = InitDiskSS(&((STRPTR)BADDR(fssm->fssm_Device))[1],fssm->fssm_Unit,fssm->fssm_Flags)))
  73.                 {
  74.                     if(!(error = InitVolumeSS()))
  75.                     {
  76.                         ULONG pktsig = 1<<(ourport->mp_SigBit);
  77.                         ULONG diskchgsig = 1<<diskchgintbit;
  78.                         ULONG udssig = 1<<(UDStimer->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
  79.                         ULONG mask = pktsig|diskchgsig|udssig;
  80.         
  81.                         error = 0;
  82.                         devnode->dol_Task = ourport;
  83.                         ReturnPacket(startuppacket, DOSTRUE, 0);
  84.         
  85.                         DoDiskInsert();
  86.             
  87.                         for(;;)
  88.                         {
  89.                             ULONG sigs;
  90.                     
  91.                             while(!( SetSignal(0,0)&mask || LoadDisk() ));
  92.         
  93.                             sigs = Wait(mask);
  94.                     
  95.                             if(sigs & pktsig)
  96.                                 DoPackets();
  97.                             if(sigs & udssig)
  98.                                 UpdateDiskStructure();
  99.                             if(sigs & diskchgsig)
  100.                             {
  101.                                 if(!inhibited)
  102.                                 {
  103.                                     /* We do the remove for security reasons */
  104.                                     DoDiskRemove();
  105.                                     DoDiskInsert();
  106.                                 }
  107.                             }
  108.                         }
  109.             
  110.                         QuitVolumeSS();
  111.                     }
  112.                     QuitDiskSS();
  113.                 }
  114.             } else error = ERROR_REQUIRED_ARG_MISSING;
  115.             CloseLibrary((struct Library*)UtilityBase);
  116.         }
  117.         CloseLibrary((struct Library*)DOSBase);
  118.     }
  119.  
  120.     if(error)
  121.         ReturnPacket(startuppacket, DOSFALSE, error);
  122. }
  123.  
  124. static BOOL MakeFSSM(BSTR startup)
  125. {
  126.     UBYTE str[258];
  127.     STRPTR src = BADDR(startup);
  128.     struct RDArgs *rdargs;
  129.  
  130.     if(src)
  131.     {
  132.         int i,len = src[0];
  133.  
  134.         /* Convert startup string */
  135.         CopyMem(&src[1], str, len);
  136.         str[len] = '\n';
  137.         str[len+1] = '\0';
  138.  
  139.         for(i=0;i<len;i++)
  140.             if(str[i] == '"') str[i] = ' ';
  141.  
  142.         if((rdargs = (struct RDArgs*)AllocDosObject(DOS_RDARGS, NULL)))
  143.         {
  144.             static char template[]=
  145.                 "D=DEVICE/A,"
  146.                 "U=UNIT/N/A,"
  147.                 "F=FLAGS/N,"
  148.                 "NS=NOAUTOSCAN/S"
  149.                 "I=INTERLEAVE/N";
  150.  
  151.             ULONG argarray[5];
  152.  
  153.             rdargs->RDA_Flags |= RDAF_NOPROMPT;
  154.             rdargs->RDA_Source.CS_Buffer = str;
  155.             rdargs->RDA_Source.CS_Length = strlen(str);
  156.             rdargs->RDA_Source.CS_CurChr = 0;
  157.  
  158.             if(ReadArgs(template, &argarray[0], rdargs))
  159.             {
  160.                 if((fssm = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC)))
  161.                 {
  162.                     struct DosEnvec *env;
  163.                     STRPTR name;
  164.  
  165.                     if((env = AllocVec(sizeof(struct DosEnvec), MEMF_PUBLIC|MEMF_CLEAR)))
  166.                     {
  167.                         if((name = AllocVec(strlen((STRPTR)argarray[0])+2, MEMF_PUBLIC)))
  168.                         {
  169.                             strcpy(name+1, (STRPTR)argarray[0]);
  170.                             name[0] = strlen(name+1);
  171.  
  172.                             fssm->fssm_Unit = *(ULONG*)argarray[1];
  173.                             fssm->fssm_Device = (BPTR)MKBADDR(name);
  174.                             fssm->fssm_Flags = argarray[2] ? *(ULONG*)argarray[2] : 16;
  175.                             fssm->fssm_Environ = (BPTR)MKBADDR(env);
  176.  
  177.                             /* These might be strange settings, but we must announce
  178.                                the device as one single track with 683 sectors, other-
  179.                                wise there would be some trouble with formatting etc. */
  180.                             env->de_TableSize = 19;
  181.                             env->de_SizeBlock = 256/4;
  182.                             env->de_Surfaces = 1;
  183.                             env->de_SectorPerBlock = 1;
  184.                             env->de_BlocksPerTrack = 683;
  185.                             env->de_LowCyl = 0;
  186.                             env->de_HighCyl = 0;
  187.                             env->de_DosType = ID_DOS_DISK;
  188.                             env->de_MaxTransfer = 256*683;
  189.                             env->de_Mask = 0x7ffffffe;
  190.                             env->de_NumBuffers = 683;
  191.                             env->de_Reserved = 1;
  192.  
  193.                             if(argarray[3])
  194.                                 autoscan = FALSE;
  195.  
  196.                             if(argarray[4])
  197.                             {
  198.                                 LONG i = *(ULONG*)argarray[4];
  199.                                 if(i>0)
  200.                                     interleave = i;
  201.                             }
  202.  
  203.                             return(TRUE);
  204.                         }
  205.  
  206.                         FreeVec(fssm);
  207.                     }
  208.                     FreeVec(fssm);
  209.                 }
  210.  
  211.                 FreeArgs(rdargs);
  212.             }
  213.  
  214.             FreeDosObject(DOS_RDARGS, rdargs);
  215.         }
  216.     }
  217.  
  218.     return(FALSE);
  219. }
  220.